import global from './global'
import { stringObjectDTO } from './dto'

/**
 * @description 时间格式化
 * @param {String} 格式化字符串 格式如：YYYY-mm-dd HH:MM:SS
 * @param {Date} date对象
 * @return {String}
 */
export function dateFormat(fmt: string, date: Date) {
    let ret
    const opt: stringObjectDTO = {
        'Y+': date.getFullYear().toString(), // 年
        'm+': (date.getMonth() + 1).toString(), // 月
        'd+': date.getDate().toString(), // 日
        'H+': date.getHours().toString(), // 时
        'M+': date.getMinutes().toString(), // 分
        'S+': date.getSeconds().toString() // 秒
        // 有其他格式化字符需求可以继续添加，必须转化成字符串
    }
    for (const k in opt) {
        ret = new RegExp('(' + k + ')').exec(fmt)
        if (ret) {
            fmt = fmt.replace(
                ret[1],
                ret[1].length === 1
                    ? opt[k]
                    : opt[k].padStart(ret[1].length, '0')
            )
        }
    }
    return fmt
}

/**
 * wait等待
 */
export function wait(timeout = 1000) {
    return new Promise(resolve => {
        setTimeout(resolve, timeout)
    })
}

export function compare(property: any) {
    return function (a: any, b: any) {
        const value1 = a[property]
        const value2 = b[property]
        return value1 - value2
    }
}

export function getDigits(str: string) {
    return str.replace(/[^0-9]/ig, '')
}
/**
 * 确认窗
 */
export async function toast(
    cont: string,
    type: 'none' | 'success' | 'loading' = 'none'
) {
    await uni.showToast({
        icon: type,
        title: cont,
        mask: true
    })
    await wait()
}

/**
 * loading显示
 */
export async function loading(
    timeout: number | null = null,
    title = '正在加载中'
) {
    await uni.showLoading({
        title,
        mask: true
    })
    // 对loading的结果回调
    if (timeout) {
        await wait(timeout)
        hideLoading()
    } else {
        console.log()
    }
}

/**
 * 隐藏loading
 */
export function hideLoading() {
    uni.hideLoading()
}

/**
 * 只有确定按钮弹窗
 */
export async function alert(cont: string, title = '提示', btnText = '确定') {
    uni.showModal({
        title,
        content: cont,
        confirmText: btnText,
        showCancel: false
    })
}

/**
 * 用户确认弹窗
 */
export async function confirm(cont: string) {
    const result = await uni.showModal({
        title: '提示',
        content: cont
    })
    if (((result as unknown) as { confirm: boolean }).confirm) {
        console.log()
    } else {
        throw new Error('操作已取消')
    }
}

// 防抖
function Anit() {
    let antiTimeStamp = 0
    return (event: { timeStamp: number }) => {
        if (
            antiTimeStamp + 1000 < event.timeStamp ||
            antiTimeStamp - 1000 > event.timeStamp ||
            event.timeStamp === 0 // 对强制不防抖处理
        ) {
            antiTimeStamp = event.timeStamp
            return true
        }
        return false
    }
}
export const anit = Anit()

// 节流
function Shake() {
    let timer = -1
    return function (obj: () => void, millisecond = 300) {
        clearTimeout(timer)
        timer = setTimeout(obj, millisecond)
    }
}
export const shake = Shake()

/*
 * @description 版本更新
 */
export async function upVersion() {
    const updateManager = uni.getUpdateManager()
    // 检查更新
    const hasUpdate = await updateManager.onCheckForUpdate(function (res) {
        return Promise.resolve(res.hasUpdate)
    })

    // 存在新版本
    if ((hasUpdate as unknown) as boolean) {
        // 监听版本更新
        updateManager.onUpdateReady(function () {
            uni.showModal({
                title: '更新提示',
                content: '新版本已经准备好，是否重启应用？',
                success(res) {
                    if (res.confirm) {
                        // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
                        updateManager.applyUpdate()
                    }
                }
            })
        })
        // 版本更新失败，需要手动更新
        updateManager.onUpdateFailed(function () {
            uni.showModal({
                // 新的版本下载失败
                title: '已经有新版本了哟~',
                content:
                    '新版本已经上线啦~，请您删除当前小程序，重新搜索打开哟~'
            })
        })
    }
}

/**
 * @description 获取用户基本信息接口，应由点击事件的方法调用，只支持微信小程序
 * @param {None}
 * @return {Promise}
 */
export function getUserProfile() {
    return new Promise((resolve, reject) => {
        // #ifdef MP-WEIXIN
        // uni.getUserProfile({
        //     desc: '用于头像的展示',
        //     success (res) {
        //         console.log(res, 'getUserProfile')
        //         resolve(JSON.parse(res.rawData))
        //     },
        //     fail (err) {
        //         reject(err)
        //     }
        // })
        // #endif
        // #ifdef MP-TOUTIAO
        uni.getUserInfo({
            success(res) {
                console.log(res, 'getUserProfile')
                resolve(JSON.parse(res.rawData))
            },
            fail() {
                throw new Error()
            }
        })
        // #endif
        // #ifdef MP-KUAISHOU
        uni.getUserInfo({
            success(res) {
                console.log(res, 'getUserProfile')
                resolve(res.userInfo)
            },
            fail() {
                throw new Error()
            }
        })
        // #endif
    })
}

/**
 * @description 图片上传接口，仅支持一个个传
 * @param { file } 微信返回的临时文件地址
 * @return { Promise }
 */
export function uploadMedia(file: string) {
    return new Promise((resolve, reject) => {
        loading(null, '文件上传中')
        console.log(file, 'file')
        uni.uploadFile({
            url: global.baseUrl + '/api/v1/job/job-position/upload',
            filePath: file,
            name: 'file',
            header: {
                'Content-Type': 'multipart/form-data'
            },
            formData: {
                user: 'test'
            },
            success(res) {
                const url = JSON.parse(res.data).msg
                resolve(url)
            },
            fail(err) {
                reject(err)
            },
            complete() {
                hideLoading()
            }
        })
    })
}

/**
 * @description 本地存储方法，批量异步键值对存储
 * @param {{key:value}} data 对象类型 应为键值对
 * @return {None}
 */
export async function setStorage(data: { [key: string]: string }) {
    const list = []
    for (const i in data) {
        list.push(
            new Promise<void>((resolve, reject) => {
                uni.setStorage({
                    key: i,
                    data: data[i],
                    success() {
                        resolve()
                    },
                    fail(err) {
                        reject(err)
                    }
                })
            })
        )
    }
    await Promise.all(list)
}

/**
 * Base64转文件
 */
export function base64ToLoaclFile(base64: string, fileName: string) {
    let path: string
    // #ifdef MP-WEIXIN
    path = wx.env.USER_DATA_PATH + '/' + fileName
    // #endif
    // #ifdef MP-TOUTIAO
    path = 'ttfile://user/' + fileName
    // #endif
    return new Promise((resolve, reject) => {
        uni.getFileSystemManager().writeFile({
            filePath: path,
            data: base64,
            encoding: 'base64',
            success: () => {
                resolve(path)
            },
            fail: err => {
                console.log(err)
                reject(err)
            }
        })
    })
}
/**
 * 本地文件转BASE64
 */
export function loaclFileToBase64(
    loacl: string,
    ishead = false
): Promise<string> {
    return new Promise(resolve => {
        uni.getFileSystemManager().readFile({
            filePath: loacl, // 选择图片返回的相对路径
            encoding: 'base64', // 编码格式
            success: res => {
                // 成功的回调
                resolve((ishead ? 'data:image/jpeg;base64,' : '') + res.data)
            },
            fail: err => {
                throw new Error(err.errMsg)
            }
        })
    })
}
/**
 * 错误日志上传
 */
export function addLog(data: { platform: string; content: string }) {
    uni.request({
        url: 'https://cloudcode.51zidan.com/api/log/',
        data,
        method: 'GET'
    })
}

export function goApp(
    url: string,
    config: {
        status?: number
        isRedirect?: number | boolean
    } = {}
) {
    config.status = Number(config.status)
    const goto = () => {
        // 如果传的url是空的
        if (!url) {
            toast('应用维护中，请稍后再试')
            return 0
        }

        // 判断应用类型，不同类型做不同的跳转方法
        if (/^https?:\/\//.test(url)) {
            url = '/pages/web-view/index?path=' + url
            // H5应用
            if (config.isRedirect) {
                uni.redirectTo({
                    url
                })
            } else {
                uni.navigateTo({
                    url
                })
            }
        } else if (/^external:\/\//.test(url)) {
            // 外部应用   应用格式    external://appId/path
            url = url.split('external://')[1]
            const list = url.split('/')
            const appId = list.splice(0, 1).join()
            const path = '/' + list.join('/')
            uni.navigateToMiniProgram({
                appId,
                path
            })
        } else if (/^applet::/.test(url)) {
            // 小程序内部路径    链接格式    applet::小程序路径       如 applet::/index/index
            url = url.split('applet::')[1]
            if (config.isRedirect) {
                uni.redirectTo({
                    url
                })
            } else {
                uni.navigateTo({
                    url
                })
            }
        } else if (/^tab::/.test(url)) {
            // 小程序tab路径     链接格式    tab::小程序路径       如 tab::/index/index
            url = url.split('tab::')[1]
            uni.switchTab({
                url
            })
        }
    }
    if (global.env === 'release') {
        switch (config.status) {
            case 0:
                goto()
                break

            case 1:
                toast('应用建设中')
                break

            case 2:
                toast('应用维护中，请稍后再试')
                break

            case 3:
                toast('应用已下线')
        }
    } else {
        goto()
    }
}

export async function uploadFile(
    tempFilePath: string
): Promise<{
    file_name: string
    external_url: string
    preview_url: string
    file_id: string
}> {
    return new Promise((resolve, reject) => {
        loading()
        uni.uploadFile({
            name: 'iFile',
            url: global.baseUrl + '/upload/file',
            filePath: tempFilePath,
            header: {
                'access-token': global.token
            },
            success(data) {
                hideLoading()
                const data2: {
                    data: {
                        fileInfo: {
                            file_name: string
                            external_url: string
                            preview_url: string
                            file_id: string
                        }
                    }
                } = JSON.parse(data.data)
                if (!data2?.data?.fileInfo) {
                    toast('文件上传失败！')
                    throw new Error('文件上传失败')
                }
                resolve(data2.data.fileInfo)
            },
            fail() {
                toast('文件上传失败！')
                throw new Error('文件上传失败')
            }
        })
    })
}

export async function openDocument(url: string, fileName: string) {
    const file = wx.env.USER_DATA_PATH + '/' + fileName
    const obj = {
        showMenu: true,
        filePath: file,
        fail(err: any) {
            console.log(err)
        }
    }
    console.log('downloadFile')
    await wx.downloadFile({
        url,
        filePath: file
    })
    await wait(500)
    await uni.openDocument(obj)
    return true
}
/**
 *
 * @param {string} url 路径
 * @param {boolean} ishead 是否需要增加base64头
 * @returns {Promise<string>}
 */
export function urlTobase64(url: any, ishead = false) {
    return new Promise((reslove) => {
        wx.request({
            url,
            responseType: 'ArrayBuffer', // 最关键的参数，设置返回的数据格式为arraybuffer
            success: res => {
                // 把arraybuffer转成base64
                let base64 = uni.arrayBufferToBase64(res.data)
                // 不加上这串字符，在页面无法显示的哦
                base64 = (ishead ? 'data:image/jpeg;base64,' : '') + base64
                // 打印出base64字符串，可复制到网页校验一下是否是你选择的原图片呢
                reslove(base64)
            }
        })
    })
}
export function toBase64(url: string, ishead: boolean = false) {
    return new Promise(resolve => {
        wx.downloadFile({
            url: url,
            success(res) {
                wx.getFileSystemManager().readFile({
                    filePath: res.tempFilePath,
                    encoding: 'base64',
                    success: result => {
                        let base64 = result.data
                        base64 = (ishead ? 'data:image/jpeg;base64,' : '') + base64
                        resolve(base64);
                    }
                })
            }
        })
    })
}
// 常用方法抛出
export default {
    toast,
    confirm,
    alert,
    wait,
    dateFormat,
    toBase64
}
